﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Extensil.Common;
using System.IO;
using Extensil.Processor;
using Extensil.Category.Settings;
using Extensil.Common.Progress;
using Extensil.Common.CategoryHandler;

namespace Extensil.Category
{
    public partial class CategorySetting : BaseSetting
    {
        ProgressUpdate pUpdate;
        public static BackgroundWorker bw = new BackgroundWorker();
        delegate void AlterCategory(object sender, DoWorkEventArgs e);
        public CategorySetting()
        {
            InitializeComponent();

            pUpdate = new ProgressUpdate("@LogMessage");
            pUpdate.TopLevel = false;
            pUpdate.Dock = DockStyle.Fill;
            pUpdate.FormBorderStyle = FormBorderStyle.None;
            splitContainer1.Panel2.Controls.Add(pUpdate);
            pUpdate.Show();
            dgvCategories.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dgvCategories_DataBindingComplete);
            LoadCategories();
        }

        void dgvCategories_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            dgvCategories.Columns["Path"].Visible = false;
            dgvCategories.Columns["Order"].Visible = false;
            dgvCategories.Columns["AutoStart"].Visible = false;
            dgvCategories.Columns["Visibility"].Visible = false;
            dgvCategories.Columns["HotKey"].ReadOnly = true;
            if(dgvCategories.Rows.Count > 0)
                dgvCategories.Rows[0].Selected = false;
            foreach(DataGridViewRow dr in dgvCategories.Rows)
            {
                ((DataGridViewImageCell)dr.Cells["SelfStart"]).Value = bool.Parse(dr.Cells["AutoStart"].Value.ToString().ToLower())
                    ? Extensil.Properties.Resources.enable
                    : Extensil.Properties.Resources.disable;

                ((DataGridViewImageCell)dr.Cells["Visible"]).Value = bool.Parse(dr.Cells["Visibility"].Value.ToString().ToLower())
                    ? Extensil.Properties.Resources.enable
                    : Extensil.Properties.Resources.disable;
            }
        }

        void LoadCategories()
        {
            dgvCategories.DataSource = CategoryFactory.SortedCategoriesDataSet;
        }

        private void txtCategoryPlugin_TextChanged(object sender, EventArgs e)
        {
            btnSubmit.Enabled = true;
        }
        void btnBrowse_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "Zipped Folder(*.zip)|";
            if(openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                txtCategoryPlugin.Text = openFileDialog1.FileName;
                btnSubmit.Enabled = true;
            }
        }

        void btnSubmit_Click(object sender, EventArgs e)
        {
            RunWorkerProcess(AddCategory, null);
        }
        void RunWorkerProcess(AlterCategory aCat, object param)
        {
            bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.WorkerSupportsCancellation = true;
            bw.DoWork += new DoWorkEventHandler(aCat);
            bw.ProgressChanged += new ProgressChangedEventHandler(InstallManager_Event);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
            if(aCat.Method.Name == "RemoveCategory")
                bw.RunWorkerAsync(param);
            else
                bw.RunWorkerAsync();
        }
        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ReloadForm();
            btnSubmit.Enabled = false;
        }
        void InstallManager_Event(object sender, ProgressChangedEventArgs e)
        {
            ProgressStatus ts = (ProgressStatus)e.UserState;
            pUpdate.Add(ts, e.ProgressPercentage);
        }
        void AddCategory(object sender, DoWorkEventArgs e)
        {
            try
            {
                PluginManager pm = new PluginManager(txtCategoryPlugin.Text, ReportStatus);
                InstallResult res = pm.Install();
                if(res.IsSuccessFull)
                    bw.ReportProgress(100, new ProgressStatus(StatusSource.Main, "New category installed successfully.", -1));
                else
                {
                    string message = "Some of the plugins could not be installed properly.";
                    foreach(Exception exc in res)
                        message += "\r\n\t" + exc.Message;

                    AlertBox.ShowDialog(message);
                }
            }
            catch(Exception exc)
            {
                AlertBox.ShowDialog(exc);
            }
        }
        public void ReportStatus(int progress, string message)
        {
            bw.ReportProgress(progress,
                new ProgressStatus(StatusSource.Task,
                message, 100));
        }
        void RemoveCategory(object sender, DoWorkEventArgs e)
        {
            try
            {
                PluginManager pm = new PluginManager(ReportStatus);
                if(pm.Uninstall(e.Argument.ToString()))
                    bw.ReportProgress(100, new ProgressStatus(StatusSource.Main, "Category '" + e.Argument.ToString() + "' removed successfully.", -1));
            }
            catch(Exception exc)
            {
                AlertBox.ShowDialog(exc);
            }
        }

        private void pbDeleteCategory_Click(object sender, EventArgs e)
        {
            if(dgvCategories.SelectedRows.Count == 0)
            {
                AlertBox.ShowDialog("Please select a category to be deleted.");
                return;
            }
            if(AlertBox.ShowDialog("Deleting a category will remove the category and its associated contents. You will not be able to use it. \r\nAre you sure you want to delete the selected category?", "Warning", AlertBoxButtons.YesNo) == AlertResult.Yes)
            {
                foreach(DataGridViewRow dr in dgvCategories.Rows)
                {
                    if(((DataGridViewCheckBoxCell)dr.Cells["Select"]).Selected)
                        RunWorkerProcess(RemoveCategory, dr.Cells["Name"].Value.ToString());
                }
            }
        }

        private void pbMoveUp_Click(object sender, EventArgs e)
        {
            if(dgvCategories.SelectedRows[0].Index != 0)
                MoveCategory(PluginManager.MoveCategoryUp);
        }

        private void pbMoveDown_Click(object sender, EventArgs e)
        {
            if(dgvCategories.SelectedRows[0].Index != dgvCategories.Rows.Count - 1)
                MoveCategory(PluginManager.MoveCategoryDown);
        }
        delegate void MoveCategoryDelegate(string catName);
        void MoveCategory(MoveCategoryDelegate del)
        {
            if(dgvCategories.SelectedRows.Count == 0 || dgvCategories.SelectedRows.Count > 1)
            {
                AlertBox.ShowDialog("Please select one category to reorder.");
                return;
            }
            string selectedCat = dgvCategories.SelectedRows[0].Cells["Name"].Value.ToString();
            del(dgvCategories.SelectedRows[0].Cells["Name"].Value.ToString());
            ReloadForm();
            foreach(DataGridViewRow dr in dgvCategories.Rows)
            {
                if(dr.Cells["Name"].Value.ToString() == selectedCat)
                {
                    dr.Selected = true;
                    break;
                }
            }
        }

        private void dgvCategories_SelectionChanged(object sender, EventArgs e)
        {
            foreach(DataGridViewRow dr in dgvCategories.Rows)
            {
                ((DataGridViewCheckBoxCell)dr.Cells["Select"]).Value = dr.Selected;
            }
        }
        private void dgvCategories_RowLeave(object sender, DataGridViewCellEventArgs e)
        {
            if(dgvCategories.Rows[e.RowIndex].Cells["Name"].EditedFormattedValue.ToString() != dgvCategories.Rows[e.RowIndex].Cells["Name"].Value.ToString())
            {
                try
                {
                    PluginManager.Rename(dgvCategories.Rows[e.RowIndex].Cells["Name"].Value.ToString(),
                        dgvCategories.Rows[e.RowIndex].Cells["Name"].EditedFormattedValue.ToString());

                    dgvCategories.CommitEdit(DataGridViewDataErrorContexts.Commit);

                    ((ISuperForm)this.SuperForm).Reload();
                    ((SettingsForm)this.GetParentForm("SettingsForm")).Reload();
                }
                catch(Exception exc)
                {
                    AlertBox.ShowDialog(exc);
                }
            }
        }
        void ReloadForm()
        {
            try
            {
                ((ISuperForm)this.SuperForm).Reload();
                ((SettingsForm)this.GetParentForm("SettingsForm")).Reload();
            }
            catch(Exception ex)
            {
            }
            LoadCategories();
        }

        private void dgvCategories_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if(e.ColumnIndex == dgvCategories.Columns["HotKey"].Index)
            {
                SetHotKey hk = new SetHotKey(dgvCategories["HotKey", e.RowIndex].Value.ToString());
                if(hk.ShowDialog() == DialogResult.OK)
                {
                    using(ConfigModifier cm = new ConfigModifier())
                    {
                        cm.SetHotkeyOfCategory(dgvCategories["Name", e.RowIndex].Value.ToString(), hk.Tag.ToString());
                        dgvCategories["HotKey", e.RowIndex].Value = hk.Tag.ToString();
                    }
                    ReloadForm();
                }
            }
            else if(e.ColumnIndex == dgvCategories.Columns["Visible"].Index)
            {
                using(ConfigModifier cm = new ConfigModifier())
                {
                    DataGridViewCell cellName = dgvCategories["Name", e.RowIndex];
                    DataGridViewImageCell cell = (DataGridViewImageCell)dgvCategories["Visible", e.RowIndex];
                    cell.Value = cm.ToggleVisibilityOfCategory(cellName.Value.ToString())
                    ? Extensil.Properties.Resources.enable
                    : Extensil.Properties.Resources.disable;
                }
                ReloadForm();
            }
            else if(e.ColumnIndex == dgvCategories.Columns["SelfStart"].Index)
            {
                using(ConfigModifier cm = new ConfigModifier())
                {
                    DataGridViewCell cellName = dgvCategories["Name", e.RowIndex];
                    DataGridViewImageCell cell = (DataGridViewImageCell)dgvCategories["SelfStart", e.RowIndex];
                    cell.Value = cm.ToggleAutoStartOfCategory(cellName.Value.ToString())
                    ? Extensil.Properties.Resources.enable
                    : Extensil.Properties.Resources.disable;
                }
            }
        }
    }
}
